﻿using System;
using System.Collections.Generic;
using System.Text;
using NetworkLib.Utilities;

namespace PokemonBattle.BattleNetwork.Client
{
    public class PokemonBattleClientHelper
    {
        public static ByteArray GetByteArray(int method, DataByteArray data)
        {
            var byteArray = new ByteArray();
            byteArray.WriteInt(method);
            data.Write(byteArray);
            return byteArray;
        }

        public static ByteArray GetByteArray(EnumPokemonBattleMethods method, DataByteArray data)
        {
            return GetByteArray((int)method, data);
        }


        public static ByteArray Logon(string identity, BattleMode modeInfo, string versionInfo)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt((int)EnumPokemonBattleMethods.Server_Logon_Hash);
            byteArray.WriteUTF(identity);

            BattleModeHelper.WriteToByteArray(byteArray, modeInfo);

            byteArray.WriteUTF(versionInfo);


            return byteArray;
        }

        public static ByteArray ReceiveMove(PlayerMove move)
        {
            return GetByteArray(EnumPokemonBattleMethods.Server_ReceiveMove_Hash, move);
        }

        public static ByteArray ReceiveTeam(byte position, string identity, ByteSequence team)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt((int)EnumPokemonBattleMethods.Server_ReceiveTeam_Hash);
            byteArray.WriteByte(position);

            byteArray.WriteUTF(identity);

            team.Write(byteArray);


            return byteArray;
        }

        public static ByteArray Exit(string identity)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt((int)EnumPokemonBattleMethods.Server_Exit_Hash);
            byteArray.WriteUTF(identity);


            return byteArray;
        }

        public static ByteArray TimeUp(string identity)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt((int)EnumPokemonBattleMethods.Server_TimeUp_Hash);
            byteArray.WriteUTF(identity);


            return byteArray;
        }

        public static ByteArray ReceiveTieMessage(string identity, TieMessage message)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt((int)EnumPokemonBattleMethods.Server_ReceiveTieMessage_Hash);
            byteArray.WriteUTF(identity);

            TieMessageHelper.WriteToByteArray(byteArray, message);

            return byteArray;
        }

        public static ByteArray RegistObsever(int identity)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt((int)EnumPokemonBattleMethods.Server_RegistObsever_Hash);
            byteArray.WriteInt(identity);

            return byteArray;
        }

        public static ByteArray ReceiveBattleInfo(BattleInfo info)
        {
            return GetByteArray(EnumPokemonBattleMethods.Server_ReceiveBattleInfo_Hash, info);
        }

        public static ByteArray ReceiveBattleSnapshot(BattleSnapshot snapshot)
        {
            return GetByteArray(EnumPokemonBattleMethods.Server_ReceiveBattleSnapshot_Hash, snapshot);
        }

        public static bool InterpretMessage(int sessionID, ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            byteArray.BypassHeader();
            var methodID = (EnumPokemonBattleMethods)byteArray.ReadInt();

            switch (methodID)
            {

                case EnumPokemonBattleMethods.Client_LogonSuccess_Hash:
                    return OnLogonSuccess(byteArray, clientService);

                case EnumPokemonBattleMethods.Client_LogonFail_Hash:
                    return OnLogonFail(byteArray, clientService);

                case EnumPokemonBattleMethods.Client_ReceiveRandomSeed_Hash:
                    return OnReceiveRandomSeed(byteArray, clientService);

                case EnumPokemonBattleMethods.Client_ReceiveMove_Hash:
                    return OnReceiveMove(byteArray, clientService);

                case EnumPokemonBattleMethods.Client_ReceiveTeam_Hash:
                    return OnReceiveTeam(byteArray, clientService);

                case EnumPokemonBattleMethods.Client_ReceiveRules_Hash:
                    return OnReceiveRules(byteArray, clientService);

                case EnumPokemonBattleMethods.Client_ReceiveTieMessage_Hash:
                    return OnReceiveTieMessage(byteArray, clientService);

                case EnumPokemonBattleMethods.Client_Exit_Hash:
                    return OnExit(byteArray, clientService);

                case EnumPokemonBattleMethods.Client_TimeUp_Hash:
                    return OnTimeUp(byteArray, clientService);

                case EnumPokemonBattleMethods.Client_RegistObsever_Hash:
                    return OnRegistObsever(byteArray, clientService);

                case EnumPokemonBattleMethods.Client_ReceiveBattleInfo_Hash:
                    return OnReceiveBattleInfo(byteArray, clientService);

                case EnumPokemonBattleMethods.Client_ReceiveBattleSnapshot_Hash:
                    return OnReceiveBattleSnapshot(byteArray, clientService);

            }

            byteArray.Rewind();
            return false;
        }

        private static bool OnLogonSuccess(ByteArray byteArray, IPokemonBattleClientService clientService)
        {

            clientService.OnLogonSuccess();
            return true;
        }

        private static bool OnLogonFail(ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            string message = byteArray.ReadUTF();

            clientService.OnLogonFail(message);
            return true;
        }

        private static bool OnReceiveRandomSeed(ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            int seed = byteArray.ReadInt();

            clientService.OnReceiveRandomSeed(seed);
            return true;
        }

        private static bool OnReceiveMove(ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            var move = DataByteArray.FromByteArray<PlayerMove>(byteArray);

            clientService.OnReceiveMove(move);
            return true;
        }

        private static bool OnReceiveTeam(ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            byte position = byteArray.ReadByte();
            string identity = byteArray.ReadUTF();
            ByteSequence team = new ByteSequence();
            team.Read(byteArray);

            clientService.OnReceiveTeam(position, identity, team);
            return true;
        }

        private static bool OnReceiveRules(ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            var rules = DataByteArray.FromByteArray<BattleRuleSequence>(byteArray);

            clientService.OnReceiveRules(rules);
            return true;
        }

        private static bool OnReceiveTieMessage(ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            string identity = byteArray.ReadUTF();
            TieMessage message = TieMessageHelper.ReadFromByteArray(byteArray);

            clientService.OnReceiveTieMessage(identity, message);
            return true;
        }

        private static bool OnExit(ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            string identity = byteArray.ReadUTF();

            clientService.OnExit(identity);
            return true;
        }

        private static bool OnTimeUp(ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            string identity = byteArray.ReadUTF();

            clientService.OnTimeUp(identity);
            return true;
        }

        private static bool OnRegistObsever(ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            int identity = byteArray.ReadInt();

            clientService.OnRegistObsever(identity);
            return true;
        }

        private static bool OnReceiveBattleInfo(ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            var info = DataByteArray.FromByteArray<BattleInfo>(byteArray);

            clientService.OnReceiveBattleInfo(info);
            return true;
        }

        private static bool OnReceiveBattleSnapshot(ByteArray byteArray, IPokemonBattleClientService clientService)
        {
            var snapshot = DataByteArray.FromByteArray<BattleSnapshot>(byteArray);

            clientService.OnReceiveBattleSnapshot(snapshot);
            return true;
        }
    }
}
